Pointerova aritmetika
Otázka od: Zdenek Moravec
10. 12. 2002 15:51
Zdravim vsechny,
pokud je napr. pWords: pointer a pomoci getmem (pWords, 1000 * sizeof
(someRecord)) vyalokuji buffer pro tisic recordu, jak se potom dostanu napr.
na 70. z nich ?
Ja pouzivam konstrukci pWord = Ptr (longint (Addr (pWords^)) + (70-1) *
sizeof (someRecord)). Ma nekdo lepsi napad ? Pripadne napad jak usporne
vyuzivat pamet k ulozeni dat bez zbytecne rezie, kterou prinasi ruzne TListy
a TCollectiony apod. a s moznosti najednou nacist nebo zapsat celou tuto
mnozinu recordu prikazem BlockRead resp. Blockwrite do souboru ?
S pozdravem (Regards)
Zdenek Moravec moravec@digitech.cz
Odpovedá: Delphin
10. 12. 2002 15:59
Zkus to takto, vysledek bude stejne rychly, ale pocitat bude za tebe
prekladac.
type TRec=record
x:integer;
end;
PRecords=^TRecords;
TRecords=array [0..100] of TRec;
var Records:PRecords;
begin
getmem(Records,1000*sizeof(TRec));
Records^[70].x:=1;
----- Original Message -----
From: "Zdenek Moravec" <zmo@volny.cz>
To: "Konference Delphi" <delphi-l@clexpert.cz>
Sent: Tuesday, December 10, 2002 2:54 PM
Subject: Pointerova aritmetika
> Zdravim vsechny,
>
> pokud je napr. pWords: pointer a pomoci getmem (pWords, 1000 * sizeof
> (someRecord)) vyalokuji buffer pro tisic recordu, jak se potom dostanu
napr.
> na 70. z nich ?
>
> Ja pouzivam konstrukci pWord = Ptr (longint (Addr (pWords^)) + (70-1) *
> sizeof (someRecord)). Ma nekdo lepsi napad ? Pripadne napad jak usporne
> vyuzivat pamet k ulozeni dat bez zbytecne rezie, kterou prinasi ruzne
TListy
> a TCollectiony apod. a s moznosti najednou nacist nebo zapsat celou tuto
> mnozinu recordu prikazem BlockRead resp. Blockwrite do souboru ?
>
> S pozdravem (Regards)
> Zdenek Moravec moravec@digitech.cz
>
>
>
>
Odpovedá: Tom xXx
10. 12. 2002 16:11
Coz takhle pouzit stary dobry Pascal se vsim vsudy???
type
tWords = array [1 .. 1000] of Word;
pWords = ^tWords;
var
MyWords:pWords;
begin
.....
new(Mywords);
MyWords[70] := 1234;
//Uz nepotrebuji
dispose(MyWords);
end;
Pro pripad tech souboru, nebylo by dobre pouzit mapovani do pameti????
T.
Odpovedá: Tom xXx
10. 12. 2002 16:06
Sorry, zapomnel jsem na zobacek
MyWords^[70] := 1234;
T.
Odpovedá: Zdenek Moravec
10. 12. 2002 15:55
Dekuji za pomoc, je to opravdu velmi efektivni - funguje dokonce i array
[0..0] of TRec.
S pozdravem (Regards)
Zdenek Moravec zmo@volny.cz
> Zkus to takto, vysledek bude stejne rychly, ale pocitat bude za tebe
> prekladac.
>
> type TRec=record
> x:integer;
> end;
> PRecords=^TRecords;
> TRecords=array [0..100] of TRec;
>
> var Records:PRecords;
> begin
> getmem(Records,1000*sizeof(TRec));
>
> Records^[70].x:=1;
>
Odpovedá: Ondrej Kelle
10. 12. 2002 16:18
> pokud je napr. pWords: pointer a pomoci getmem (pWords,
> 1000 * sizeof(someRecord)) vyalokuji buffer pro tisic recordu,
> jak se potom dostanu napr. na 70. z nich ?
>
> Ja pouzivam konstrukci pWord = Ptr (longint (Addr (pWords^))
> + (70-1) * sizeof (someRecord)). Ma nekdo lepsi napad ?
Napadaju ma dva sposoby, mozes pouzit pointer aritmetics alebo array
typecast, napriklad:
type
PMyRecord = ^TMyRecord;
TMyRecord = record
MyInt: Integer;
MyStr: array[0..255] of Char;
end;
TMyRecords = array[0..0] of TMyRecord;
const
Count = 20;
var
Buf: Pointer;
P: PMyRecord;
I: Integer;
begin
Buf := AllocMem(Count * SizeOf(TMyRecord));
try
// fill in some data...
P := Buf;
for I := 0 to Count - 1 do
begin
with P^ do
begin
MyInt := I;
StrLCopy(MyStr, PChar(IntToStr(I)), SizeOf(MyStr) - 1);
end;
Inc(P);
end;
// iterate using pointer arithmetics
P := Buf;
for I := 0 to Count - 1 do
begin
with P^ do
OutputDebugString(PChar(Format('record %d: MyInt = %d, MyStr =
''%s''', [I,
MyInt, MyStr])));
Inc(P);
end;
// iterate using array typecast
for I := 0 to Count - 1 do
with TMyRecords(Buf^)[I] do
OutputDebugString(PChar(Format('record %d: MyInt = %d, MyStr =
''%s''', [I,
MyInt, MyStr])));
finally
FreeMem(Buf);
end;
end;
> Pripadne napad jak usporne vyuzivat pamet k ulozeni dat
> bez zbytecne rezie, kterou prinasi ruzne TListy a TCollectiony
> apod.
TList ma podla mna zanedbatelnu reziu, hlavne ak si vopred nastavis
Capacity, pritom kod s jeho pouzitim byva o nieco citatelnejsi.
> a s moznosti najednou nacist nebo zapsat celou tuto
> mnozinu recordu prikazem BlockRead resp. Blockwrite
> do souboru ?
Na to potrebujes mat suvisly blok dat, takze v tom pripade TList odpada.
Mozno by sa Ti hodil nejaky objekt, ktory bude vnutorne pouzivat
TMemoryStream. V nom mas vlastnost Memory, ku ktorej mozes pristupovat
horeuvedenym sposobom, ale ma tiez sikovnu metodu SaveToFile
HTH
TOndrej
Odpovedá: Petr Vones
10. 12. 2002 18:48
From: "Zdenek Moravec" <zmo@volny.cz>
> Ja pouzivam konstrukci pWord = Ptr (longint (Addr (pWords^)) + (70-1) *
> sizeof (someRecord)). Ma nekdo lepsi napad ? Pripadne napad jak usporne
> vyuzivat pamet k ulozeni dat bez zbytecne rezie, kterou prinasi ruzne TListy
> a TCollectiony apod. a s moznosti najednou nacist nebo zapsat celou tuto
> mnozinu recordu prikazem BlockRead resp. Blockwrite do souboru ?
Dynamicka pole
Petr Vones